package com.lagou.mall.esflow.core.config;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("all")
public enum ThreadPoolManager {
    // 导出线程池
    EXPORT(20, 50, 120, 100, "export_threadPool"),
    // 导入线程池
    IMPORT(20, 50, 120, 100, "import_threadPool"),
    // 查询线程池
    QUERY(40, 60, 60, 500, "query_threadPool"),


    JOB(4, 10, 100, 300, "job_threadPool"),

    ;

    private final ThreadPoolExecutor threadPool;

    ListeningExecutorService coreExecutorService;

    /**
     * 构建线程池
     *
     * @param coreSize 核心线程数
     * @param maxSize 最大线程数
     * @param aliveTime 最大存活多少秒
     * @param queueSize 队列大小
     * @param name 线程名称
     */
    ThreadPoolManager(int coreSize, int maxSize, int aliveTime, int queueSize, String name) {
        threadPool = new ThreadPoolExecutor(coreSize, maxSize, aliveTime, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(queueSize),
                new TaskThreadFactory(name),
                new TaskDiscardPolicy()
        );
        coreExecutorService = MoreExecutors.listeningDecorator(threadPool);
    }

    /**
     * 手动向线程池中添加可返回任务
     *
     * @param task 任务
     * @param <T> 返回类型
     * @return 返回结果Future
     */
    public <T> ListenableFuture<T> submitTask(Callable<T> task) {
        return coreExecutorService.submit(task);
    }

    /**
     * 手动向线程池中添加可返回任务
     *
     * @param task 任务
     */
    public void executeTask(Runnable task) {
        coreExecutorService.execute(task);
    }

    public ThreadPoolExecutor getThreadPool() {
        return threadPool;
    }

    /**
     * 提供基于Guava的线程回调函数注册机制的方法
     *
     * @param task 执行task
     * @param callable 需要注册的回调函数
     * @param <T> 范型参数
     */
    public <T> void callBack(Callable<T> task, FutureCallback<T> callable) {
        ListenableFuture<T> future = this.submitTask(task);
        Futures.addCallback(future, callable);
    }

}
